package com.zg.autoflow.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zg.autoflow.req.SettleWorkflowStepReq;
import com.zg.autoflow.service.SettleWorkflowStepService;
import com.zg.autoflow.service.SettleWorkflowStepSubService;
import com.zg.autoflow.vo.SettleWorkflowStepVo;
import com.zg.common.core.constant.RedisKeyContants;
import com.zg.common.core.dao.autoflow.dao.SettleWorkflowInstanceDao;
import com.zg.common.core.dao.autoflow.dao.SettleWorkflowStepDao;
import com.zg.common.core.dao.autoflow.entity.SettleWorkflowInstance;
import com.zg.common.core.dao.autoflow.entity.SettleWorkflowStep;
import com.zg.common.core.dao.autoflow.entity.SettleWorkflowStepSub;
import com.zg.common.core.util.CollectionUtils;
import com.zg.common.core.util.RedisUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author zg
 */
@Service
@RequiredArgsConstructor
public class SettleWorkflowStepServiceImpl implements SettleWorkflowStepService {

    private final SettleWorkflowStepDao settleWorkflowStepDao;
    private final SettleWorkflowStepSubService settleWorkflowStepSubDao;
    private final SettleWorkflowInstanceDao settleWorkflowInstanceDao;
    private final RedisUtil redisUtil;

    @Override
    public List<SettleWorkflowStep> getNextStepConfig(SettleWorkflowStepReq settleWorkflowStepReq) {
        SettleWorkflowInstance settleWorkflowInstance = settleWorkflowInstanceDao.getOne(new LambdaQueryWrapper<SettleWorkflowInstance>().eq(SettleWorkflowInstance::getInstCode, settleWorkflowStepReq.getInstCode()));
        SettleWorkflowStep settleWorkflowStep = settleWorkflowStepDao.getOne(new LambdaQueryWrapper<SettleWorkflowStep>().eq(SettleWorkflowStep::getFlowCode, settleWorkflowInstance.getFlowCode()).eq(SettleWorkflowStep::getStepCode, settleWorkflowStepReq.getStepCode()));
        if (settleWorkflowStep != null && settleWorkflowStep.getNextStep() != null) {
            String[] nextStepCodes = settleWorkflowStep.getNextStep().split(",");

            //如果符合分支环节 用分支的
            SettleWorkflowStepSub curSubFlowStepSub = settleWorkflowStepSubDao.getCurSubFlowStepSub(settleWorkflowInstance, settleWorkflowStepReq.getStepCode());
            if (curSubFlowStepSub != null) {
                nextStepCodes = curSubFlowStepSub.getNextStepId().split(",");
            }
            List<SettleWorkflowStep> nextStepList = getFlowStep(settleWorkflowInstance.getFlowCode(), nextStepCodes);
            return nextStepList;
        }
        return Collections.emptyList();
    }

    @Override
    public Map<String, SettleWorkflowStep> getFlowAllStepMap(String flowCode) {
        //从redis中获取
        String key = RedisKeyContants.SETTLE_FLOW_STEP + flowCode;
        Map<String, SettleWorkflowStep> map = redisUtil.hmget(key, SettleWorkflowStep.class);
        if (map != null && map.size() > 0) {
            return map;
        }
        //查询列表
        LambdaQueryWrapper<SettleWorkflowStep> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SettleWorkflowStep::getFlowCode, flowCode);
        List<SettleWorkflowStep> list = settleWorkflowStepDao.list(queryWrapper);
        map = CollectionUtils.collectionToMap(list, SettleWorkflowStep::getStepCode);
        redisUtil.hmset(key, map, RedisKeyContants.DEFAULT_SAVE_TIME);
        return map;
    }

    @Override
    public List<SettleWorkflowStep> getFlowStep(String flowCode, String[] nextStepCodes) {
        if (nextStepCodes == null || nextStepCodes.length == 0) {
            return new ArrayList<>();
        }
        List<SettleWorkflowStep> list = new ArrayList<>();

        Map<String, SettleWorkflowStep> flowAllStepMap = getFlowAllStepMap(flowCode);

        for (String stepcode : nextStepCodes) {
            SettleWorkflowStep step = flowAllStepMap.get(stepcode);
            list.add(step);
        }
        list.sort(new Comparator<SettleWorkflowStep>() {
            @Override
            public int compare(SettleWorkflowStep o1, SettleWorkflowStep o2) {
                if (o1.getSeq() == null && o2.getSeq() == null) {
                    return 0;
                }
                if (o1.getSeq() == null) {
                    return -1;
                }
                if (o2.getSeq() == null) {
                    return 1;
                }
                return (int) (o1.getSeq() - o2.getSeq());
            }
        });
        return list;
    }
}
